Regional 2014 Gearter NY

这是昨天做的一套比赛,2014年的一场北美地区赛,就不把题目挂上来了,直接放题意和代码吧。
题目网址在此

##A·Height Ordering
一眼题,求一串数列冒泡排序时进行操作的次数。比赛的时候是队友做出来的,只要懂如何写冒泡排序即可,复杂度为O(N^2)。

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
    int t;
    cin >> t;
    while(t--)
    {
        int cnt,a[20],sum = 0;
        cin >> cnt;
        for(int i = 0;i < 20;i++)
            cin >> a[i];
        for(int i = 0;i < 20;i++)
        {
            for(int j = i;j < 20;j++)
            {
                if(a[i] > a[j])
                {
                    sum++;
                    swap(a[i],a[j]);
                }
            }
        }
        cout << cnt << " " << sum << endl;
    }
    return 0;
}

##B·Islands in the Data Stream
一眼题,当时这道题目是我做的,队友表示看不懂这道题目的意思,我根据他的样例脑补了一下规律。就是每次删除一串数列中最小的一个数,求剩余的子串数,需要注意的是可能会有重复计算,如 0,1,0,0,2,0,如果不排除重复计算的结果,答案则为3,所以这里用set进行处理,最后输出set的size即可。

#include<iostream>
#include<set>
#include<map>
#include<algorithm>
using namespace std;

int main(){
    int t;
    cin >> t;
    while(t--)
    {
        int cnt,a[12];
        set<int>st;
        set<pair<int,int> > mp;
        cin >> cnt;
        for(int i = 0;i < 12;i++)
        {
            cin >> a[i];
            st.insert(a[i]);
        }
        set<int>::iterator it = st.begin();
        int siz = st.size();
        while(siz--)
        {
            for(int i = 0;i < 12;i++)
            {
                if(a[i] == *it)
                    a[i] = -1;
            }
            int ok = 0,flag = 0;
            for(int i = 0;i < 12;i++)
            {
                if(ok)
                {
                    if(a[i] != -1)
                    {
                        continue;
                    }
                    else
                    {
                        ok = 0;
                        mp.insert(make_pair(flag,i - 1));
                    }
                }
                else
                {
                    if(a[i] != -1)
                    {
                        ok = 1;
                        flag = i;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            it++;
        }
        cout << cnt << " " << mp.size() << endl;
    }
    return 0;
}

##C·Floating-Point Format Conversion
听浙大的大神们说是什么一道浮点精度的模拟题(?)有很多判断的条件,ORZZ暂时没看懂,留坑待填

##D·Happy Happy Prime Prime
一眼题,给出一个数先判断这个数是不是素数,如果是素数,判断其经过一定的运算之后能否成为1,运算为对数上每一位的数进行平方求和,注意加上vis判断,防止死循环。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

bool isprime(int x)
{
    if(x == 1 || x == 2)
        return false;
    for(int i = 2;i * i <= x;i++)
    {
        if(x % i == 0)
            return false;
    }
    return true;
}
int main(){
    int t;
    cin >> t;
    while(t--)
    {
        int cnt,n,vis[1 << 16];
        cin >> cnt >> n;
        cout << cnt << " " << n;
        if(!isprime(n))
        {
            cout << " NO\n";
        }
        else
        {
            memset(vis,0,sizeof(vis));
            while(!vis[n] && n != 1)
            {
                int te = 0;
                vis[n] = 1;
                while(n)
                {
                    te += (n % 10) * (n % 10);
                    n /= 10;
                }
                n = te;
            }
            if(n == 1)
                cout << " YES\n";
            else
                cout << " NO\n";
        }
    }
    return 0;
}

##E·Mancala
规律题,ORZ比赛的时候明明非常接近规律了可就是死活没推出来啊,赛后一经点拨就恍然大悟
QAQ买不起专业版的MDPAD2,就不发图了,大意就是给出几个筒子,让你放几个小点进去,每次的操作是找到一个筒子满足b[n]=n,就将其中的小点全部分配给前面的筒子,直到最后所有的小点都在第一个筒子里面。规律就是每次都会把一个筒清空,那么就用递推就行了,从前一个的情况往后一个情况推,每次多出一个满的筒子,最后保存答案,离线回答一下就行了。

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;

int main(){
    int mark[2000][80],siz[2000];
    siz[0] = 1,mark[0][0] = 1;
    for(int i = 1;i < 2000;i++)
    {
        for(int j = 0;j < siz[i - 1];j++)
        {
            mark[i][j] = mark[i - 1][j];
        }
        siz[i] = siz[i - 1];
        int ok = 0,pos;
        for(int j = 0;j < siz[i];j++)
        {
            if(mark[i][j] == 0)
            {
                ok = 1;
                pos = j;
                break;
            }
        }
        if(ok)
        {
            for(int j = 0;j < pos;j++)
            {
                mark[i][j]--;
            }
            mark[i][pos] = pos + 1;
        }
        else
        {   
            for(int j = 0;j < siz[i];j++)
            {
                mark[i][j]--;
            }
            siz[i]++;
            mark[i][siz[i] - 1] = siz[i];
        }
    }
    int t;
    cin >> t;
    while(t--)
    {
        int cnt,n;
        cin >> cnt >> n;
        cout << cnt << " " << siz[n - 1] << endl;
        for(int i = 0;i < siz[n - 1];i++)
        {
            if(i % 10 == 0)
                cout << mark[n - 1][i];
            else
                cout << " " << mark[n - 1][i];
            if((i + 1) % 10 == 0 || i == siz[n - 1] - 1)
                cout << endl;
        }
    }
    return 0;
}

##F·A Rational Sequence
队友做出来的,题意就是构造一棵树,满足三个条件:

The label of the root is 1/1

The left child of label p/q is p/(p + q)

The right child of label p/q is (p + q)/q

给你一个节点,让你求下一个节点是多少。
当时是队友做出来的,暂不明,待填

##G·Growing Rectangular Spiral
这道题是我做的,题意是一个点由原点出发,依照右上左下的次序运动,每次运动出来的直线至少比前一条长1,现在给你一个坐标,让你判断这个点能否到达这个坐标,输出使到达这个坐标最短的路径的方法。当时我做出了一个假设,如果能到达的话,最多只需要6次,然后要先判断这个坐标的横坐标是不是小于纵坐标,如果成立就做两次,否则判断能不能做6次到,六条线的长度分别为1,2,3,x+5-y,x+2,x+3。代码就不放了,最简单的if判断而已

##F·Farey Sums
找规律题,给你一个n,找出所有的a/b满足(0 < a <= b)且a与b互质,将其升序排序,然后求b[i]的分母/b[i+1]的分母的和,规律是每加入一对互质的数,就会让最终答案+3,搞一搞就出来了。然而我并没有在比赛的时候发现这个规律……果然含是我的脑洞不够大的缘故吗。8-20ps:代码是写出来的结果交上去T了,然后我又离线搞了一下,才1w的数组竟然不让提交我也醉了,估计把代码扔着吧。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

int gcd(int x,int y)
{
    return (y == 0 ? x : gcd(y,x % y));
}

int main(){
    //freopen("h.in","r",stdin);
    //freopen("h.txt","w",stdout);
    int mark[10005];
    mark[2] = 4;
    for(int i = 3;i <= 10000;i++)
    {
        mark[i] = mark[i - 1];
        for(int j = 1;j < i;j++)
        {
            if(gcd(i,j) == 1)
                mark[i] += 3;
        }
    }
    int t;
    cin >> t;
    while(t--)
    {
        int cnt,n;
        cin >> cnt >> n;
        cout << cnt << " " << mark[n] + 1 << "/2\n";
    }
    return 0;
}

##I·The Queen’s Super-circular Patio
迷之数学,并不能懂……

热评文章